﻿using SimCaptcha.Interface;
using SimCaptcha.Models;
using System;
using System.Collections.Generic;
//using System.Drawing;
//using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System.Numerics;
using SixLabors.Fonts;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Jpeg;

// Project: SimCaptcha
// https://github.com/yiyungent/SimCaptcha
// Author: yiyun <yiyungent@gmail.com>

namespace SimCaptcha.AspNetCore
{
    public class AspNetCoreVCodeImage : IVCodeImage
    {
        public static List<FontFamily> Fonts = new List<FontFamily>();

        public VCodeImgModel Create(string code, int width, int height)
        {
            VCodeImgModel rtnResult = new VCodeImgModel { VCodePos = new List<PointPosModel>() };

            // TODO: 变化点: 答案: 4个字
            int rightCodeLength = 4;


            string bgImagesDir = Path.Combine(Environment.CurrentDirectory, "SimCaptcha", "bgImages");
            string[] bgImagesFiles = System.IO.Directory.GetFiles(bgImagesDir);
            if (bgImagesFiles == null || bgImagesFiles.Length == 0)
            {
                Console.WriteLine("SimCaptcha/bgImages 需放置背景图片");
                throw new Exception("SimCaptcha/bgImages 需放置背景图片");
            }

            Random random = new Random();
            int imgIndex = random.Next(bgImagesFiles.Length);
            string randomImgFile = bgImagesFiles[imgIndex];
            Color[] colorArray = { Color.Black, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };

            if (Fonts.Count <= 0)
            {
                string fontDir = Path.Combine(Environment.CurrentDirectory, "SimCaptcha", "fonts");
                var files = Directory.GetFiles(fontDir);

                var fonts = new List<FontFamily>();
                foreach (var item in files)
                {
                    var fontCollection = new FontCollection();
                    fonts.Add(fontCollection.Add(File.Open(item, System.IO.FileMode.Open)));
                }

                if (fonts == null || fonts.Count == 0)
                {
                    Console.WriteLine("SimCaptcha/fonts 需放置字体文件 .ttf");
                    throw new Exception("SimCaptcha/fonts 需放置字体文件 .ttf");
                }
                Fonts = fonts;
            }

            List<string> words = new List<string>();

            using (var image = Image.Load(randomImgFile))
            {
                image.Mutate(o =>
                {
                    int code_length = code.Length;
                    for (int i = 0; i < code_length; i++)
                    {
                        int colorIndex = random.Next(colorArray.Length);
                        int fontIndex = random.Next(Fonts.Count);
                        var font = new Font(Fonts[fontIndex], 15);

                        int _y = random.Next(height);
                        if (_y > (height - 30))
                            _y = _y - 60;

                        int _x = width / (i + 1);
                        if ((width - _x) < 50)
                        {
                            _x = width - 60;
                        }
                        string word = code.Substring(i, 1);
                        if (rtnResult.VCodePos.Count < rightCodeLength)
                        {
                            (int, int) percentPos = ToPercentPos((width, height), (_x, _y));
                            // 添加正确答案 位置数据
                            rtnResult.VCodePos.Add(new PointPosModel()
                            {
                                X = percentPos.Item1,
                                Y = percentPos.Item2,
                            });
                            words.Add(word);
                        }
                        o.DrawText(word, font, colorArray[colorIndex], new PointF(_x, _y));
                    }
                });
                var imageEncoder = new JpegEncoder
                {
                    Quality = 95,
                    ColorType = JpegColorType.Rgb
                };

                var ms = new MemoryStream();
                image.Save(ms, imageEncoder);
                ms.Dispose();
                rtnResult.VCodeTip = "请依次点击" + String.Join("", words);
                rtnResult.Words = words;


                rtnResult.ImgBase64 = "data:image/jpg;base64," + Convert.ToBase64String(ms.GetBuffer());
            }
            return rtnResult;
        }


        /// <summary>
        /// 转换为相对于图片的百分比单位
        /// </summary>
        /// <param name="widthAndHeight">图片宽高</param>
        /// <param name="xAndy">相对于图片的绝对尺寸</param>
        /// <returns>(int:xPercent, int:yPercent)</returns>
        protected (int, int) ToPercentPos((int, int) widthAndHeight, (int, int) xAndy)
        {
            (int, int) rtnResult = (0, 0);
            // 注意: int / int = int (小数部分会被截断)
            rtnResult.Item1 = (int)(((double)xAndy.Item1) / ((double)widthAndHeight.Item1) * 100);
            rtnResult.Item2 = (int)(((double)xAndy.Item2) / ((double)widthAndHeight.Item2) * 100);

            return rtnResult;
        }


        /*   /// <summary>
           /// 加载字体
           /// </summary>
           /// <param name="path">字体文件路径,包含字体文件名和后缀名</param>
           /// <param name="size">大小</param>
           /// <param name="fontStyle">字形(常规/粗体/斜体/粗斜体)</param>
           protected Font LoadFont(string path, int size, FontStyle fontStyle)
           {
               try
               {
                   System.Drawing.Text.PrivateFontCollection pfc = new System.Drawing.Text.PrivateFontCollection();

                   pfc.AddFontFile(path);// 字体文件的路径

                   Font myFont = new Font(pfc.Families[0], size, fontStyle);

                   return myFont;
               }
               catch (System.Exception)
               {
                   return null;
               }
           }*/
    }


}
